home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright William Schelter. All rights reserved. This file does
- the low level relocation which tends to be very system dependent.
- It is included by the file sfasl.c
- */
-
- #define EXTERNAL_P(rel) \
- relocation_info.r_type & )
-
- #define HI12 0xfff00000
- #define LO20 ~HI12
-
- foo(){};
- relocate()
- {
- char *where;
-
- {unsigned int new_value;
- char tem [10];
- #ifdef DEBUG
- printf("\nEnter relocate:*srelocation_info {r_symndx= %d, r_vaddr = %d,:",
- relocation_info.r_symndx,
- relocation_info.r_vaddr
- );fflush(stdout);
- #endif
- where = the_start + relocation_info.r_vaddr;
-
- if(relocation_info.r_symndx < S_BSS){
- #ifdef DEBUG
- printf("(relocation_info.r_symndx = %d < S_BSS)",relocation_info.r_symndx
- );fflush(stdout);
- print_name(&symbol_table[relocation_info.r_symndx]);
- #endif
- switch(relocation_info.r_type){
- case R_KCALL:
- /* instructions like balix take a 20 bit argument
- which wants to be the displacement in half words to
- from the address of the instruction to the actual
- address. */
- {int displ;
- unsigned int new;
- displ= symbol_table[relocation_info.r_symndx].n_value -
- (int)where;
- new= *(unsigned int *)where;
-
- /* *(unsigned int *)where
- = (new & HI12) | ((displ >> 1) & LO20); */
- /* need to store the halves separately, because word pointers
- must be aligned */
- ((unsigned short *)where)[0]=0x8b00;
- ((unsigned short *)where)[1]=0x0c00;
- return ;}
- case R_PCRBYTE: /* byte (pc relative) */
- case R_PCRWORD: /* word (pc relative) */
- case R_PCRLONG: /* word (pc relative) */
- new_value= - (int)start_address
- + symbol_table[relocation_info.r_symndx].n_value;
- break;
- default:
- { new_value=
- symbol_table[relocation_info.r_symndx].n_value;}}}
- else
- { switch(relocation_info.r_symndx){
- case S_DATA: case S_BSS: case S_TEXT:
- new_value= (int)start_address;
- break;
- default:
- dprintf(relocation_info.r_type = %d, relocation_info.r_type);
- #ifdef DEBUG
- printf("\nrelocation_info {r_symndx= %d, r_vaddr = %d, Ignored:",
- relocation_info.r_symndx,
- relocation_info.r_vaddr
- );fflush(stdout);
- #endif
- goto DONT;}
- };
- dprintf((type %d),relocation_info.r_type);
- switch(relocation_info.r_type){
- case R_RELBYTE:
- case R_PCRBYTE:
- *( char *)where = new_value + *( char *) where;
- break;
- case R_RELWORD:
- case R_PCRWORD:
- *( short *)where = new_value + *( short *) where;
- break;
- case R_RELLONG:
- case R_PCRLONG:
- /* I guess it must be long if in these areas
- I don't see how the size can vary.
- */
- if (((int)where %4) !=0) FEerror("long alignment not long aligned",0,0);
- *( long *)where = new_value + *( long *) where;
- break;
- default:
- printf("(bad type %d)",relocation_info.r_type);
- }
- DONT:;
- }
- }
-
- typedef int (*FUNC)();
-
-
-
- /* #define describe_sym(n) do{if (debug){printf("Sym No %d:",n); print_name(symbol_table+ (n));}}while(0)
- */
-
- /* #include "spadutils.c" */
-
-
-